#include "EleccionABM.h"
#include <limits>
using namespace ABM;

//Cuando llamo al constructor de IAbm , le seteo el nombre del ABM en el que estoy.
EleccionABM::EleccionABM() :
	IAbm("Eleccion") {
	this->manejadorEleccion = new ManejadorEleccion();
	this->manejadorDistrito = new ManejadorDistrito();
	this->manejadorCargo = new ManejadorCargo();
}

bool EleccionABM::alta() {

	bool existenLosIdentificadoresExternos = true;
	bool resultado = false;
	int fecha = -1;
	string cargo = "";
	string distrito = "";
	unsigned int distritosParaAgregar = 0;

	cout << "Ingrese la FECHA de la eleccion: ";
	cin >> fecha;
	cin.ignore(numeric_limits<streamsize>::max(), '\n');

	cout << "Ingrese el nombre del CARGO: ";
	getline(cin, cargo);
	cargo = Utils::aMinuscula(cargo);

	existenLosIdentificadoresExternos = this->manejadorCargo->existe(cargo);

	if (existenLosIdentificadoresExternos) {

		Eleccion* eleccionAInsertar = new Eleccion();
		eleccionAInsertar->setFecha(fecha);
		eleccionAInsertar->setCargo(cargo);

		cout << endl << "Ingrese cuantos distritos desea agregar: ";
		cin >> distritosParaAgregar;
		cin.ignore(numeric_limits<streamsize>::max(), '\n');

		for (unsigned int i = 0; i < distritosParaAgregar; i++) {
			cout << "Ingrese el nombre del DISTRITO nro " << i+1  << " a agregar: ";
			getline(cin, distrito);
			distrito = Utils::aMinuscula(distrito);

			if (this->manejadorDistrito->existe(distrito))
				eleccionAInsertar->agregarDistrito(distrito);
			else {
				existenLosIdentificadoresExternos = false;
				break;
			}
		}

		if (existenLosIdentificadoresExternos && this->manejadorEleccion->alta(
				eleccionAInsertar)) {
			resultado = true;
		}

		delete eleccionAInsertar;

	} else {
		cout << "No existe el cargo" << endl;
		getchar();
		resultado = false;
	}

	return resultado;
}

bool EleccionABM::baja() {

	bool resultado = false;

	bool existenLosIdentificadoresExternos = true;

	int fecha = -1;
	string cargo = "";
	string distrito = "";

	cout << "Ingrese la FECHA de la eleccion: ";
	cin >> fecha;
	cin.ignore(numeric_limits<streamsize>::max(), '\n');

	cout << "Ingrese el nombre del CARGO: ";
	getline(cin, cargo);
	cargo = Utils::aMinuscula(cargo);

	existenLosIdentificadoresExternos = this->manejadorCargo->existe(cargo);

	if (existenLosIdentificadoresExternos) {

		Eleccion* eleccionABorrar = new Eleccion();
		eleccionABorrar->setFecha(fecha);
		eleccionABorrar->setCargo(cargo);

		if (this->manejadorEleccion->baja(eleccionABorrar)) {
			resultado = true;

		} else
			resultado = false;

		delete eleccionABorrar;

	} else {
		cout << "No existe el cargo" << endl;
		getchar();
		resultado = false;

	}

	return resultado;

}

bool EleccionABM::modificacion() {

	bool resultado;
	bool existenLosIdentificadoresExternos = true;

	int fecha = -1;
	string cargo = "";
	string distrito = "";

	system("clear");
	cout << "Ingrese la FECHA de la eleccion: ";
	cin >> fecha;
	cin.ignore(numeric_limits<streamsize>::max(), '\n');

	cout << "Ingrese el nombre del CARGO: ";
	getline(cin, cargo);
	cargo = Utils::aMinuscula(cargo);

	existenLosIdentificadoresExternos = this->manejadorCargo->existe(cargo);

	if (existenLosIdentificadoresExternos) {

		Eleccion* eleccionAModificar = new Eleccion();
		eleccionAModificar->setFecha(fecha);
		eleccionAModificar->setCargo(cargo);

		Eleccion* eleccionModificada = new Eleccion(eleccionAModificar);

		bool existenLosIdentificadoresExternos = this->menuModificacion(
				eleccionModificada);

		if (existenLosIdentificadoresExternos
				&& this->manejadorEleccion->modificacion(eleccionAModificar,
						eleccionModificada)) {
			resultado = true;

		} else
			resultado = false;

		delete eleccionAModificar;
		delete eleccionModificada;

	} else {
		cout << "No existe el cargo" << endl;
		getchar();
		resultado = false;
	}

	return resultado;

}

bool EleccionABM::menuModificacion(Eleccion* eleccionModificada) {

	unsigned int campoAModificar = 0;
	bool sigue = true;
	bool fin = false;
	while (!fin) {
		system("clear");
		campoAModificar = 0;
		cout << "Ingrese el campo que desea modificar " << endl;
		cout << "               1- Fecha" << endl;
		cout << "               2- Cargo" << endl;
		cout << "               3- Distritos" << endl;
		cout << "       4- Volver" << endl;
		cin >> campoAModificar;
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		if (campoAModificar < 5 && campoAModificar > 0)
			fin = true;
		else {
			cout << "Opcion incorrecta" << endl;
			getchar();
		}

	}

	switch (campoAModificar) {
	case (1): {
		unsigned int fecha = -1;
		cout << endl << "Ingrese la FECHA de la eleccion: ";
		cin >> fecha;
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		eleccionModificada->setFecha(fecha);
		break;
	}
	case (2): {
		string cargo = "";
		cout << "Ingrese el nombre del CARGO: ";
		getline(cin, cargo);
		cargo = Utils::aMinuscula(cargo);

		if (this->manejadorCargo->existe(cargo))
			eleccionModificada->setCargo(cargo);
		else
			cout << endl << "El cargo ingresado no existe ";

		break;
	}
	case (3): {
		unsigned int distritosParaAgregar = 0;
		cout << endl << "Ingrese cuantos distritos desea agregar: ";
		cin >> distritosParaAgregar;
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		for (unsigned int i = 0; i < distritosParaAgregar; i++) {
			string distrito = "";
			cout << "Ingrese el nombre del DISTRITO no" << i << " a agregar: ";
			getline(cin, distrito);
			distrito = Utils::aMinuscula(distrito);

			if (this->manejadorDistrito->existe(distrito))
				eleccionModificada->agregarDistrito(distrito);
			else
				cout << "El distrito ingresado no existe " << endl;
		}
		break;
	}
	case (4): {
		sigue = false;
	}
	}

	return sigue;
}

void EleccionABM::altaMasiva() {
	ArchivoAltasMasivas* arch = new ArchivoAltasMasivas("eleccionesCargaMasiva.txt");
	string linea;
	Eleccion* eleccion;
	vector<string>* campos;

	string fecha;
	string cargo;
	string distrito;

	linea = arch->leerLinea();

	while (!arch->finDeArchivo()) {
		eleccion = new Eleccion();
		campos = Parser::separarCampos(&linea, separadorCampos);

		//si no tiene por lo menos tres elementos, estaba mal la línea del archivo, lo descarto
		if (campos->size() >= 3) {
			for (unsigned int i = 0; i < campos->size(); ++i) {
				Parser::reemplazarCaracter(&campos->at(0), separadorPalabras,
						blanco);
			}
			fecha = Utils::aMinuscula(campos->at(0));
			cargo = Utils::aMinuscula(campos->at(1));
			if (this->manejadorCargo->existe(cargo)) {
				eleccion->setFecha(atoi(fecha.c_str()));
				eleccion->setCargo(cargo);
			}
			//agrego los distritos
			for (unsigned int j = 2; j < campos->size(); ++j) {
				distrito = Utils::aMinuscula(campos->at(j));
				if (this->manejadorDistrito->existe(distrito)) {
					eleccion->agregarDistrito(distrito);
					distrito.clear();
				}
			}
			this->manejadorEleccion->alta(eleccion);
		}
		fecha.clear();
		cargo.clear();
		delete eleccion;
		delete campos;
		linea = arch->leerLinea();
		this->log->escribir("Se genero Alta Masiva de Eleccion.");
	}
	delete arch;
}

EleccionABM::~EleccionABM() {
delete this->manejadorDistrito;
delete this->manejadorCargo;
delete this->manejadorEleccion;
}
